package mapper

import (
	"bufio"
	"io"
	"strconv"
	"strings"

	"loggo/setting"
)

var conf configuration

func init() {
	conf.err = setting.Load("cfg/map.json", &conf)
}

func SetConfFile(path string) err {
	return setting.Load(path, &conf)
}

func value(s string, t Type) (interface{}, error) {
	switch t {
	case Int:
		return strconv.ParseInt(s, 10, 64)
	case Float:
		return strconv.ParseFloat(s, 64)
	case String:
		return s, nil
	}
	return nil, ErrType
}

// 从一行日志到字典的映射
// s 是一行日志
// separator 是日志分隔符，一般是空格
// fields 是自定义的数据结构，包括类型，名称和对应日志位置
func _map(s string) (Line, error) {
	line := make(map[string]Block)
	ss := strings.Split(s, conf.Sep)

	var t Type
	for _, m := range conf.Map {
		b := &Block{}

		b.Type, err = NewType(m.Type)
		if err != nil {
			return nil, err
		}

		b.value, err = value(s, b.Type)
		if err != nil {
			return nil, err
		}

		line[b.Name] = *b
	}
	return line
}

func MapLine(line string) (Line, error) {
	if conf.err != nil {
		return nil, conf.err
	}
	return _map(line, conf.Sep, conf.Map)
}

func MapFile(f *os.File) (file File, err error) {
	r := bufio.NewReader(f)
	for {
		line, err = r.ReadString('\n')

		if err == io.EOF {
			err = nil
			return
		}

		if err != nil {
			return
		}

		l, err := MapLine(line)
		if err != nil {
			return
		}

		f = append(f, l)
	}
	return
}
